//
//  QRCodeViewController.swift
//  PersonnalDiary
//
//  Created by 徐宽阔 on 15/9/29.
//  Copyright © 2015年 XDKOO. All rights reserved.
//

import UIKit
import AVFoundation

class QRCodeViewController: UIViewController , UITabBarDelegate {

    @IBAction func closeBtnClick(sender: UIBarButtonItem) {
        dismissViewControllerAnimated(true, completion: nil)
    }
    
    @IBOutlet weak var toolBar: UITabBar!
    
    @IBOutlet weak var container: UIView!
    
    @IBOutlet weak var containerHeightCons: NSLayoutConstraint!
    
    @IBOutlet weak var scanlineView: UIImageView!
    
    @IBOutlet weak var scanlineTopCons: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        toolBar.delegate = self
        toolBar.selectedItem = toolBar.items![0]
    }
    
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        // 1. 执行扫描动画
        startAnimation()
        // 2. 开始扫描二维码
        startScanQRCode()
    }
    
    
    func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem)
    {
        containerHeightCons.constant = (item.tag == 1) ? 150 : 300
        
        scanlineView.layer.removeAllAnimations()
        
        startAnimation()
        
    }
    
    private func startAnimation()
    {
        scanlineTopCons.constant = -containerHeightCons.constant
        view.layoutIfNeeded()
        
        UIView.animateWithDuration(2.0) { [unowned self] () -> Void in
            UIView.setAnimationRepeatCount(MAXFLOAT)
            self.scanlineTopCons.constant = self.containerHeightCons.constant
            self.view.layoutIfNeeded()
        }
    }
    
    private func startScanQRCode()
    {
        // 1.判断是否可以添加输入设备
        if !session.canAddInput(inputDevice)
        {
            return
        }
        // 2.判断是否可以添加输出对象
        if !session.canAddOutput(output)
        {
            return
        }
        // 3.添加输入和输出到会话中
        session.addInput(inputDevice)
        session.addOutput(output)
        
        // 4.设置输出解析数据类型
        output.metadataObjectTypes = output.availableMetadataObjectTypes
        
        // 5.设置输出代理,监听解析到得结果
        output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
        
        // 6.1添加预览图层
        view.layer.insertSublayer(previewLayer, atIndex: 0)
        // 6.2添加描边图层
        previewLayer.addSublayer(drawLayer)
        
        // 7.利用会话开始扫描
        session.startRunning()
    }
    
    // 1.创建输入
    private lazy var inputDevice: AVCaptureDeviceInput? =
    {
        let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        
        do{
            let input = try AVCaptureDeviceInput(device: device)
            return input
        }catch
        {
            return nil
        }
    }()
    
    // 2.创建输出
    private lazy var output: AVCaptureMetadataOutput =
    {
        let output = AVCaptureMetadataOutput()
        
        let frame = self.container.frame
        let size = self.view.frame.size
        
        // 由于是按照横屏来计算的,所以需要将x变为y,y变为x,将宽变为高,高变为宽
        output.rectOfInterest = CGRect(x: frame.origin.y / size.height, y: frame.origin.x / size.width, width: frame.size.height / size.height, height: frame.size.width / size.width)
        
        return output
    }()
    
    // 3.创建会话
    private lazy var session: AVCaptureSession =
    {
        let s = AVCaptureSession()
        // 显示很小的二维码
        s.sessionPreset = "AVCaptureSessionPreset1920x1080"
        return s
    }()
    
    // 4.创建预览图层
    private lazy var previewLayer: AVCaptureVideoPreviewLayer =
    {
        let layer = AVCaptureVideoPreviewLayer(session: self.session)
        layer.frame = UIScreen.mainScreen().bounds
        return layer
    }()
    
    // 5.创建描边图层
    private lazy var drawLayer: CALayer = {
       let layer = CALayer()
        layer.frame = UIScreen.mainScreen().bounds
        return layer
    }()

}

extension QRCodeViewController: AVCaptureMetadataOutputObjectsDelegate
{
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!)
    {
        // 先去除图层
        clearCorners()
//        metadataObjects.last?.string
        for objc in metadataObjects
        {
            let codeObjc = previewLayer.transformedMetadataObjectForMetadataObject(objc as! AVMetadataObject)
//            print((codeObjc as! AVMetadataMachineReadableCodeObject).corners)
            drawCorners(codeObjc as! AVMetadataMachineReadableCodeObject)
        }
    }
    
    private func drawCorners(codeObjc: AVMetadataMachineReadableCodeObject)
    {
        if codeObjc.corners == nil || codeObjc.corners.count == 0
        {
            return
        }
        let subLayer = CAShapeLayer()
        subLayer.lineWidth = 4
        subLayer.strokeColor = UIColor.redColor().CGColor
        subLayer.fillColor = UIColor.clearColor().CGColor
        
        let path = UIBezierPath()
        var point = CGPointZero
        var index = 0
        let dictArr = codeObjc.corners
        CGPointMakeWithDictionaryRepresentation(dictArr[index++] as! CFDictionaryRef, &point)
    
        path.moveToPoint(point)
        
        while index < dictArr.count
        {
            CGPointMakeWithDictionaryRepresentation(dictArr[index++] as! CFDictionaryRef, &point)
            path.addLineToPoint(point)
        }
        
        path.closePath()
        
        subLayer.path = path.CGPath
        
        drawLayer.addSublayer(subLayer)
    }
    
    private func clearCorners()
    {
        if drawLayer.sublayers == nil || drawLayer.sublayers?.count == 0
        {
            return
        }
        for subLayer in drawLayer.sublayers!
        {
            subLayer.removeFromSuperlayer()
        }
    }
}






















